#include "ESP8266_Config.h"

/* ============================= 配置方法 ============================= */

	/* =================== ESP8266作为客户端配置步骤 =================== */
	/*
		（1）AT
		（2）AT+RST
		（3）AT+CWMODE=1
		（4）AT+CWJAP="SSID","密码"
		（5）AT+CIPMUX=0
		（6）AT+CIPSTART="TCP","IP",端口号
		（7）AT+CIPMODE=1
		（8）AT+CIPSEND
		（9）发送数据，退出透传模式发送+++(不加回车\r\n)
	*/
	
  /* =================== ESP8266作为服务端配置步骤 =================== */
	/*
		（1）AT
		（2）AT+RST
		（3）AT+CWMODE=2
		（4）AT+CWSAP="SSID","密码",信道,0,最大连接数,0
		（5）AT+CWDHCP=0,1
		（6）AT+CIPAP="IP","网关IP","子网掩码"
		（7）AT+CIPMUX=1
		（8）AT+CIPSERVER=1,端口号
		（9）AT+CIPSEND=连接号,发送字节数
		（10）发送信息
		（11）+++停止发送信息(不加回车\r\n)
	*/

/* ============================= 全局变量定义 ============================= */

/**
 * @分类：数据缓冲区
 * @功能：存储ESP8266串口接收的数据帧
 * @作用：初始化时清零缓冲区、长度计数和完成标志，用于管理串口接收的完整数据帧
 */
struct STRUCT_USARTx_Fram strEsp8266_Fram_Record = {0}; // 初始化ESP8266数据帧记录器

/* ============================= 基础通信配置 ============================= */
/**
    ******************************************************************************
    * @分类：客户端模式初始化
    * @功能：完成ESP8266客户端模式的全流程配置（硬件到网络连接）
    * @作用：将ESP8266配置为STA模式并连接指定WiFi，建立与TCP服务器的透明传输连接
    * 输入参数：
    *   @baud：串口通信波特率（推荐115200，需与ESP8266模块波特率一致）
    * 返回值  ：无
    * 详细说明：
    * 1. 硬件初始化阶段：
    *    - 配置USART3串口参数，建立与ESP8266的物理通信链路
    *    - 退出可能残留的透明传输模式，确保AT指令可正常交互
    * 
    * 2. 模块自检阶段：
    *    - 发送AT指令验证通信链路完整性
    *    - 复位模块清除历史配置，确保初始化环境一致
    * 
    * 3. 网络接入阶段：
    *    - 配置为STA模式（仅作为客户端接入外部WiFi网络）
    *    - 阻塞等待连接到指定WiFi热点（使用USER_ESP8266_AP_SSID/PWD参数）
    *    - 获取并打印IP地址信息，确认网络接入状态
    * 
    * 4. 连接建立阶段：
    *    - 配置单连接模式（适合单一服务器通信场景）
    *    - 与指定TCP服务器建立连接（使用USER_ESP8266_TCP_SERVER参数）
    *    - 切换到透明传输模式，实现数据的直接收发
    *    - 进入发送就绪状态并退出透明模式（平衡自动通信与指令控制需求）
    * 
    * 注意事项：
    *   - WiFi连接采用阻塞等待机制，超时由ESP8266_Set_CWJAP内部实现（约5秒）
    *   - 需提前定义USER_ESP8266_AP_SSID、USER_ESP8266_AP_PWD等宏参数
    *   - 透明传输模式切换需在TCP连接建立后执行，否则会导致配置失败
    *   - 函数执行时间取决于WiFi信号强度和服务器响应速度（通常3-10秒）
    ******************************************************************************
**/
void ESP8266_Client_Config(u32 baud)
{
    // 初始化USART3硬件，设置与ESP8266通信的波特率
    USART3_Config(baud);  

	ESP8266_ATE(ATE_ON);

    // 退出可能存在的透明传输模式，确保能正常接收AT指令
    ESP8266_ExitUnvarnishSend();
    
    // 调试信息：提示正在配置ESP8266（默认注释，需开启USART1输出时取消注释）
    USART1_Printf("\r\n 正在配置 ESP8266 ...... \r\n");

    // 发送AT指令测试模块通信是否正常（验证硬件连接和基础功能）
    ESP8266_AT();

    // 复位模块到初始状态，清除之前的配置残留
    ESP8266_RST();

    // 配置模块为STA模式（仅作为客户端连接外部WiFi）
    ESP8266_Set_CWMODE(STA);

    // 循环连接指定WiFi热点，直到连接成功（阻塞操作）
    // 使用用户配置的SSID和密码（USER_ESP8266_AP_SSID/USER_ESP8266_AP_PWD）
    while(! ESP8266_Set_CWJAP(USER_ESP8266_AP_SSID, USER_ESP8266_AP_PWD));

    // 获取并打印模块的IP地址等网络信息（用于调试确认网络接入状态）
    ESP8266_Cmd("AT+CIFSR", "OK", NULL, 1000);

    // 配置为单连接模式（仅建立一个TCP连接）
    ESP8266_CIPMUX(Singel_Connection);

    // 与指定TCP服务器建立连接
    // 服务器地址和端口由USER_ESP8266_TCP_SERVER_IP/USER_ESP8266_TCP_SERVER_PORT指定
    ESP8266_CIPSTART(TCP, USER_ESP8266_TCP_SERVER_IP, USER_ESP8266_TCP_SERVER_PORT, Single_ID_0);

    // 切换到透明传输模式（发送数据无需AT指令前缀，直接发送原始数据）
    ESP8266_Set_CIPMODE(TRANSPARENT_MODE);

    // 进入数据发送状态，准备接收透明传输数据
    ESP8266_Cmd("AT+CIPSEND", "OK", NULL, 500);

    // 再次退出透明传输模式（确保后续可通过AT指令控制，按需使用）
    ESP8266_ExitUnvarnishSend();
}

/**
    ******************************************************************************
    * @分类：服务器模式初始化
    * @功能：完成ESP8266服务器模式的全流程配置（硬件到网络服务）
    * @作用：将ESP8266配置为AP模式创建WiFi热点，启动TCP服务器并支持多客户端连接
    * 输入参数：
    *   @baud：串口通信波特率（推荐115200，需与ESP8266模块波特率一致）
    * 返回值  ：无
    * 详细说明：
    * 1. 硬件初始化阶段：
    *    - 配置USART3串口参数，建立与ESP8266的物理通信链路
    *    - 退出可能残留的透明传输模式，确保AT指令可正常交互
    * 
    * 2. 模块自检阶段：
    *    - 发送AT指令验证通信链路完整性
    *    - 复位模块清除历史配置，确保初始化环境一致
    * 
    * 3. 热点配置阶段：
    *    - 配置为AP模式（创建独立WiFi热点供客户端连接）
    *    - 阻塞等待热点参数配置完成（使用USER_ESP8266_AP_SSID/PWD参数）
    *    - 启用AP模式下的DHCP服务，自动分配客户端IP地址
    *    - 配置AP模式的IP地址（默认使用空字符串保持模块默认配置）
    * 
    * 4. 服务器启动阶段：
    *    - 配置为多连接模式（支持同时与多个客户端建立连接）
    *    - 启动TCP服务器并指定监听端口和超时时间
    *    - 初始化数据发送参数，准备接收客户端连接
    *    - 退出透明传输模式，保持AT指令控制能力
    * 
    * 注意事项：
    *   - AP模式配置采用阻塞等待机制，确保热点参数设置生效
    *   - 需提前定义USER_ESP8266_AP_SSID、USER_ESP8266_AP_PWD等热点参数
    *   - 多连接模式下需通过连接ID管理不同客户端（0-4共5个可用ID）
    *   - 服务器端口号需根据实际需求配置（建议1024-65535范围）
    *   - 函数执行时间通常为2-5秒，取决于模块响应速度
    ******************************************************************************
**/
void ESP8266_Server_Config(u32 baud)
{
    // 初始化USART3硬件，设置与ESP8266通信的波特率
    USART3_Config(baud);  

    // 退出可能存在的透明传输模式，确保能正常接收AT指令
    ESP8266_ExitUnvarnishSend();
    
    // 调试信息：提示正在配置ESP8266（默认注释，需开启USART1输出时取消注释）
     USART1_Printf("\r\n 正在配置 ESP8266 服务器模式...... \r\n");

    // 发送AT指令测试模块通信是否正常（验证硬件连接和基础功能）
    ESP8266_AT();

    // 复位模块到初始状态，清除之前的配置残留
    ESP8266_RST();

    // 配置模块为AP模式（创建WiFi热点供其他设备连接）
    ESP8266_Set_CWMODE(AP);

    // 配置AP热点参数并等待完成（阻塞操作）
    // 参数：SSID、密码、信道1、WPA_PSK加密方式
    while(! ESP8266_Set_CWSAP(USER_ESP8266_AP_SSID, USER_ESP8266_AP_PWD, 1, WPA_PSK));

    // 启用AP模式下的DHCP服务器，自动为连接的客户端分配IP
    ESP8266_Set_CWDHCP(AP, DHCP_ENABLE);

    // 配置AP模式的IP地址（空字符串表示使用模块默认IP：192.168.4.1）
    // 完整格式：ESP8266_Set_CIPAP("192.168.4.1", "192.168.4.1", "255.255.255.0")
    ESP8266_Set_CIPAP("", "", "");

    // 配置为多连接模式（支持同时与多个客户端建立连接，最多5个）
    ESP8266_CIPMUX(Multi_Connection);

    // 启动TCP服务器，指定监听端口和超时时间
    // 示例：ESP8266_TCPSERVER(ENABLE, "8080", 5000) 表示在8080端口监听，超时5秒
    ESP8266_TCPSERVER(ENABLE, "8080", 5000);

    // 初始化服务器数据发送参数（多连接模式下指定连接ID为1）
    // 实际发送需在客户端连接后使用对应ID进行操作
    ESP8266_CIPSEND(DISABLE, "", 0, Multiple_ID_1);

    // 确保退出透明传输模式，保持AT指令控制能力
    ESP8266_ExitUnvarnishSend();
}

/**
    * @分类：指令处理核心
    * @功能：向ESP8266发送AT指令并验证响应
    * @作用：封装AT指令的发送、响应等待和结果判断逻辑，是所有AT指令操作的基础
    * @param  cmd：要发送的AT指令（字符串）
    * @param  reply1：期望的响应1（字符串，可为NULL）
    * @param  reply2：期望的响应2（字符串，可为NULL）
    * @param  waittime：等待响应的时间（毫秒）
    * @retval bool：true=指令执行成功（收到期望响应），false=执行失败
    * @note   工作流程：
    *         1. 清空接收缓冲区和状态标志
    *         2. 发送AT指令（自动添加回车换行）
    *         3. 等待指定时间，让ESP8266返回响应
    *         4. 检查接收缓冲区中是否包含期望响应
    */
bool ESP8266_Cmd(char *cmd, char *reply1, char *reply2, u32 waittime)
{
    strEsp8266_Fram_Record.InfAll = 0;  // 清空接收缓冲区长度和完成标志
    memset(strEsp8266_Fram_Record.Data_RX_BUF, 0, RXBUF_MAX_LEN);
    strEsp8266_Fram_Record.InfBit.FramFinishFlag = 0; // 清除帧完成标志

    ESP8266_Printf("%s\r\n", cmd);  // 通过USART3发送AT指令（添加回车换行）

    // 若无需检查响应（reply1和reply2均为NULL），直接返回成功
    if (!(reply1) && !(reply2)){
        return true;
    }

    // 等待帧接收完成或超时
    u32 tick = 0;
    while (!strEsp8266_Fram_Record.InfBit.FramFinishFlag && tick < waittime) {
        Delay_ms(1);
        tick++;
    }
    // 超时后也要清除帧完成标志
    strEsp8266_Fram_Record.InfBit.FramFinishFlag = 0;

    // 在接收缓冲区末尾添加字符串结束符，便于字符串操作
    strEsp8266_Fram_Record.Data_RX_BUF[strEsp8266_Fram_Record.InfBit.FramLength] = '\0';

    printf("%s", strEsp8266_Fram_Record.Data_RX_BUF);  // 通过USART1打印ESP8266的响应（调试用）

    // 检查响应中是否包含reply1或reply2（支持两种可能的成功响应）
    if ((reply1 != 0) && (reply2 != 0))
        return ((bool)strstr(strEsp8266_Fram_Record.Data_RX_BUF, reply1) ||
                (bool)strstr(strEsp8266_Fram_Record.Data_RX_BUF, reply2));

    // 仅检查reply1
    else if (reply1 != 0)
        return ((bool)strstr(strEsp8266_Fram_Record.Data_RX_BUF, reply1));

    // 仅检查reply2
    else
        return ((bool)strstr(strEsp8266_Fram_Record.Data_RX_BUF, reply2));
}

/**
 * @分类：缓冲区管理
 * @功能：清空ESP8266接收缓冲区
 * @作用：重置接收缓冲区数据、长度计数和完成标志，避免旧数据干扰新数据的接收和解析
 */
void ESP8266_ClearBuffer(void)
{
    strEsp8266_Fram_Record.InfAll = 0;  // 清零长度和完成标志
    memset(strEsp8266_Fram_Record.Data_RX_BUF, 0, RXBUF_MAX_LEN); // 清空数据
}

/**
 * @分类：模块状态检测
 * @功能：等待ESP8266模块就绪
 * @作用：判断模块是否完成初始化并可接收指令，通过检测"ready"响应实现
 * @param timeout_ms：最大等待时间（毫秒）
 * @retval bool：true=模块就绪，false=超时未就绪
 */
bool ESP8266_WaitReady(u32 timeout_ms)
{
    u32 tick = 0;
    while (tick < timeout_ms) {
        if (strstr(strEsp8266_Fram_Record.Data_RX_BUF, "ready")) {
            return true;
        }
        Delay_ms(1);
        tick++;
    }
    return false;
}


/******************************** AT基础指令 ************************************/
/**
    * @分类：模块控制指令
    * @功能：复位ESP8266模块
    * @作用：通过硬件复位逻辑重置模块状态，恢复初始配置
    * @param  无
    * @retval 无
    * @note   发送"AT+RST"指令，等待2500ms，检查是否返回"OK"/"ready"
    */
void ESP8266_RST(void)
{
    ESP8266_ClearBuffer();
    ESP8266_Cmd("AT+RST", "OK", "ready", 2000);
    ESP8266_WaitReady(3000); // 等待ready字符串
}

/**
    * @分类：通信测试指令
    * @功能：测试ESP8266与STM32的通信链路
    * @作用：通过发送基础"AT"指令验证串口通信是否正常，是最基础的功能测试
    * @param  无
    * @retval 无
    * @note   发送"AT"指令，若返回"OK"则通信正常
    */
void ESP8266_AT(void)
{
	ESP8266_ClearBuffer();
    ESP8266_Cmd("AT", "OK", NULL, 500);  // 发送AT指令，检查是否返回"OK"
}

/**
    * @分类：版本信息指令
    * @功能：获取ESP8266的固件版本信息
    * @作用：查询模块的固件版本，用于确认模块型号和功能支持情况
    * @param  无
    * @retval 无
    * @note   发送"AT+GMR"指令，等待500ms，检查"OK"响应
    *         响应信息会通过USART1打印（调试用）
    */
void ESP8266_GMR(void)
{
	ESP8266_ClearBuffer();
    ESP8266_Cmd("AT+GMR", "OK", NULL, 1000);  // 发送版本查询指令
}

/**
  * @分类：电源管理指令
  * @功能：设置ESP8266深度睡眠模式
  * @作用：控制模块进入低功耗状态，减少待机功耗，支持定时唤醒或外部唤醒
  * @param  time_in_us : 睡眠时间（微秒）
  *          - 0 = 无限睡眠，只能通过外部唤醒（如GPIO16接RST）
  *          - 1~268,435,454 (0xFFFFFFE) = 定时唤醒
  * @retval bool : 是否成功发送指令
  * @note   发送"AT+GSLP=<time>"指令配置深度睡眠
  */
bool ESP8266_Deep_Sleep(uint32_t time_in_us)
{
    char cmd[32];  // 存储格式化后的AT指令
    
    // 限制最大睡眠时间（ESP8266规范：最大不超过0xFFFFFFE微秒）
    if(time_in_us > 0xFFFFFFE) {
        time_in_us = 0xFFFFFFE;
    }
    
    // 格式化深度睡眠指令（AT+GSLP=睡眠时间）
    snprintf(cmd, sizeof(cmd), "AT+GSLP=%u", time_in_us);
    
	ESP8266_ClearBuffer();
    // 发送指令，等待1000ms，检查"OK"响应
    return ESP8266_Cmd(cmd, "OK", NULL, 1000);
}

/**
  * @分类：指令配置指令
  * @功能：配置ESP8266的AT指令回显功能
  * @作用：控制模块是否回显发送的AT指令，回显开启便于调试，关闭可减少数据传输量
  * @param  ATE_Status : 回显状态（ATE_ON=开启回显，ATE_OFF=关闭回显）
  * @retval bool : 配置是否成功
  * @note   ATE0关闭回显（仅返回结果），ATE1开启回显（返回指令+结果）
  */
bool ESP8266_ATE(ATE_Status_t ATE_Status)
{
    switch(ATE_Status){
        case ATE_OFF:
			ESP8266_ClearBuffer();
            return ESP8266_Cmd("ATE0", "OK", NULL, ATE_CMD_TIMEOUT_MS);  // 发送ATE0指令

        case ATE_ON:
			ESP8266_ClearBuffer();
            return ESP8266_Cmd("ATE1", "OK", NULL, ATE_CMD_TIMEOUT_MS);  // 发送ATE1指令

        default:
            ESP8266_Printf("Error: Invalid ATE status=%d\r\n", ATE_Status);  // 调试输出：无效状态
            return false;  // 返回失败
			break;
    }
}

/**
    * @分类：系统配置指令
    * @功能：恢复ESP8266的出厂设置
    * @作用：将模块所有参数重置为出厂默认值，用于清除错误配置或恢复初始状态
    * @param  无
    * @retval 无
    * @note   发送"AT+RESTORE"指令，等待2500ms，检查"OK"响应
    *         恢复后模块参数重置，需重新配置
    */
void ESP8266_Restore(void)
{
	//ESP8266_ClearBuffer();
    ESP8266_Cmd("AT+RESTORE", "OK", NULL, 5000);  // 发送恢复出厂设置指令
    Delay_ms(200); // 恢复后适当延时，等待模块稳定
}


/******************************** UART配置指令 ************************************/
/**
	* @分类：UART查询指令
	* @功能：检查ESP8266的UART当前配置（临时生效）
	* @作用：获取当前正在使用的串口参数（波特率、数据位等），用于调试和参数验证
	* @param  无
	* @retval	无
	* @note   发送"AT+UART_CUR?"指令，等待500ms，检查"OK"响应
		 	 如果未通过 AT+UART_CUR 修改过，则返回模块启动时的默认值（通常与 AT+UART_DEF 相同）
	*/
void ESP8266_Check_UART_CUR(void)
{
	//ESP8266_ClearBuffer();
    ESP8266_Cmd("AT+UART_CUR?", "OK", NULL, 500);
}

/**
	* @分类：UART查询指令
	* @功能：检查ESP8266的UART默认配置（永久生效）
	* @作用：获取掉电后仍保持的串口参数，用于确认重启后生效的配置
	* @param  无
	* @retval	无
	* @note   发送"AT+UART_DEF?"指令，查询模块保存的默认串口参数
	*/
void ESP8266_Check_UART_DEF(void)
{
	//ESP8266_ClearBuffer();
	ESP8266_Cmd("AT+UART_DEF?", "OK", NULL, 500);
}

/**
	* @分类：UART查询指令（兼容旧版本）
	* @功能：检查ESP8266的UART配置（兼容旧固件）
	* @作用：为旧版本固件提供串口参数查询支持，确保兼容性
	* @param  无
	* @retval	无
	* @note   发送"AT+UART?"指令，兼容早期固件的串口参数查询
	*/
void ESP8266_Check_UART(void)
{
	//ESP8266_ClearBuffer();
	ESP8266_Cmd("AT+UART?", "OK", NULL, 500);
}

/**
	* @分类：UART配置指令（临时生效）
	* @功能：设置ESP8266的UART当前配置（重启后失效）
	* @作用：动态修改串口参数，用于临时调试或适配不同通信场景
	* @param  波特率、数据位（5-8）、停止位（1-3）、校验位（0-2）、流控（0-3）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+UART_CUR"指令，设置临时生效的串口参数
	*/
bool ESP8266_Set_UART_CUR(u32 baudrate, u8 databits, u8 stopbits, u8 parity, u8 flow_control)
{
	char cCmd[32];

	if(databits < 5 || databits > 8)	{USART1_Printf("error,databits range 5~8\n");		return false;}
	if(stopbits < 1 || stopbits > 3)	{USART1_Printf("error,stopbits range 1~3\n"); 		return false;}
	if(parity	> 2)					{USART1_Printf("error,parity   range 0~2\n");		return false;}
	if(flow_control > 3)				{USART1_Printf("error,flow_control range 0~3\n"); 	return false;}

	snprintf(cCmd, sizeof(cCmd), "AT+UART_CUR=%u,%u,%u,%u,%u", baudrate, databits, stopbits, parity, flow_control);

	//ESP8266_ClearBuffer();
	return ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/**
	* @分类：UART配置指令（永久生效）
	* @功能：设置ESP8266的UART默认配置（重启后仍生效）
	* @作用：配置掉电保存的串口参数，确保模块重启后使用预设的通信参数
	* @param  波特率、数据位（5-8）、停止位（1-3）、校验位（0-2）、流控（0-3）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+UART_DEF"指令，设置永久生效的串口参数
	*/
bool ESP8266_Set_UART_DEF(u32 baudrate, u8 databits, u8 stopbits, u8 parity, u8 flow_control)
{
    char cCmd[32];

	if(databits < 5 || databits > 8)	{USART1_Printf("error,databits range 5~8\n");		return false;}
	if(stopbits < 1 || stopbits > 3)	{USART1_Printf("error,stopbits range 1~3\n"); 		return false;}
	if(parity	> 2)					{USART1_Printf("error,parity   range 0~2\n");		return false;}
	if(flow_control > 3)				{USART1_Printf("error,flow_control range 0~3\n"); 	return false;}

	snprintf(cCmd, sizeof(cCmd), "AT+UART_DEF=%u,%u,%u,%u,%u", baudrate, databits, stopbits, parity, flow_control);

	//ESP8266_ClearBuffer();
	return ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/**
	* @分类：UART配置指令（兼容旧版本）
	* @功能：设置ESP8266的UART配置（兼容旧固件）
	* @作用：为旧版本固件提供串口参数配置支持，确保兼容性
	* @param  波特率、数据位（5-8）、停止位（1-3）、校验位（0-2）、流控（0-3）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+UART"指令，兼容早期固件的串口参数设置
	*/
bool ESP8266_Set_UART(u32 baudrate, u8 databits, u8 stopbits, u8 parity, u8 flow_control)
{
	char cCmd[32];

	if(databits < 5 || databits > 8)	{USART1_Printf("error,databits range 5~8\n");		return false;}
	if(stopbits < 1 || stopbits > 3)	{USART1_Printf("error,stopbits range 1~3\n"); 		return false;}
	if(parity	> 2)					{USART1_Printf("error,parity   range 0~2\n");		return false;}
	if(flow_control > 3)				{USART1_Printf("error,flow_control range 0~3\n"); 	return false;}

	snprintf(cCmd, sizeof(cCmd), "AT+UART=%u,%u,%u,%u,%u", baudrate, databits, stopbits, parity, flow_control);

	//ESP8266_ClearBuffer();
	return ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/******************************** 系统功能指令 ************************************/
/**
	* @分类：睡眠模式查询指令
	* @功能：查询ESP8266当前睡眠模式
	* @作用：获取模块当前的睡眠配置，用于确认低功耗策略是否生效
	* @param  无
	* @retval	无
	* @note   发送"AT+SLEEP?"指令，查询当前睡眠模式参数
	*/
void ESP8266_Check_SLEEP(void)
{
    ESP8266_Cmd("AT+SLEEP?", "OK", NULL, 100);
}

/**
	* @分类：睡眠模式配置指令
	* @功能：设置ESP8266的睡眠模式
	* @作用：配置模块的睡眠策略（如轻度睡眠、无睡眠等），平衡功耗与响应速度
	* @param  sleep_time：睡眠模式参数（具体值对应不同睡眠策略）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+SLEEP=<参数>"指令，设置模块睡眠模式
	*/
bool ESP8266_Set_SLEEP(u8 sleep_time)
{
    char cCmd[36];

    snprintf(cCmd, sizeof(cCmd), "AT+SLEEP=%u", sleep_time);

    return ESP8266_Cmd(cCmd, "OK", "ERROR", 200);
}

/**
	* @分类：系统资源查询指令
	* @功能：查询ESP8266的RAM使用情况
	* @作用：获取当前RAM总量和剩余量，用于调试内存溢出问题
	* @param  无
	* @retval	无
	* @note   发送"AT+SYSRAM?"指令，获取RAM使用信息
	*/
void ESP8266_Check_SYSRAM(void)
{
	ESP8266_Cmd("AT+SYSRAM?", "OK", NULL, 200);
}

/**
	* @分类：硬件信息查询指令
	* @功能：查询ESP8266的ADC输入值
	* @作用：获取内置ADC检测的电压值，可用于电池电压监测等场景
	* @param  无
	* @retval	无
	* @note   发送"AT+SYSADC?"指令，获取ADC采样值
	*/
void ESP8266_Check_SYSADC(void)
{
	ESP8266_Cmd("AT+SYSADC?", "OK", NULL, 200);
}


/******************************** GPIO控制指令 ************************************/
/**
	* @分类：GPIO配置查询指令
	* @功能：查询ESP8266指定GPIO的配置
	* @作用：获取指定引脚的工作模式和上拉状态，用于调试硬件连接
	* @param  pin：GPIO引脚编号
	* @retval	无
	* @note   发送"AT+SYSIOGETCFG=<pin>"指令，查询引脚配置
	*/
void ESP8266_SYSIOGETCFG(u8 pin)
{
	char cCmd[20];

	snprintf(cCmd, sizeof(cCmd), "AT+SYSIOGETCFG=%u", pin);

	ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/**
	* @分类：GPIO模式配置指令
	* @功能：配置ESP8266指定GPIO的工作模式和上拉状态
	* @作用：设置引脚的功能模式（如GPIO、专用功能等）和上拉/下拉状态
	* @param  pin：GPIO引脚编号；mode：工作模式；pull_up：上拉状态
	* @retval	无
	* @note   发送"AT+SYSIOSETCFG=<pin>,<mode>,<pull_up>"指令，配置引脚基础参数
	*/
void ESP8266_SYSIOSETCFG(u8 pin, u8 mode, PULL_UP_Status_t pull_up)
{
	char cCmd[24];

	snprintf(cCmd, sizeof(cCmd), "AT+SYSIOSETCFG=%u, %u, %u", pin, mode, pull_up);

	ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/**
	* @分类：GPIO方向配置指令
	* @功能：设置ESP8266指定GPIO的输入/输出方向
	* @作用：配置引脚为输入或输出模式，为后续读写操作做准备
	* @param  pin：GPIO引脚编号；dir：方向（输入/输出）
	* @retval	无
	* @note   发送"AT+SYSGPIODIR=<pin>,<dir>"指令，设置引脚方向
	*/
void ESP8266_SYSGPIODIR(u8 pin, GPIO_WORK_MODE_t dir)
{
	char cCmd[24];

	snprintf(cCmd, sizeof(cCmd), "AT+SYSGPIODIR=%u, %u", pin, dir);

	ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/**
	* @分类：GPIO输出控制指令
	* @功能：设置ESP8266指定GPIO的输出电平
	* @作用：控制输出引脚的高低电平，用于驱动外部设备（如LED、继电器等）
	* @param  pin：GPIO引脚编号；level：输出电平（高/低）
	* @retval	无
	* @note   发送"AT+SYSGPIOWRITE=<pin>,<level>"指令，设置输出电平
	*/
void ESP8266_SYSGPIOWRITE(u8 pin, GPIO_WRITE_t level)
{
	char cCmd[24];

	snprintf(cCmd, sizeof(cCmd), "AT+SYSGPIOWRITE=%u, %u", pin, level);

	ESP8266_Cmd(cCmd, "OK", NULL, 500);

}

/**
	* @分类：GPIO输入读取指令
	* @功能：读取ESP8266指定GPIO的输入电平
	* @作用：获取输入引脚的当前状态，用于检测外部信号（如按键、传感器等）
	* @param  pin：GPIO引脚编号
	* @retval	无
	* @note   发送"AT+SYSGPIOREAD=<pin>"指令，读取输入电平
	*/
void ESP8266_SYSGPIOREAD(u8 pin)
{
	char cCmd[24];

	snprintf(cCmd, sizeof(cCmd), "AT+SYSGPIOREAD=%u", pin);

	ESP8266_Cmd(cCmd, "OK", NULL, 500);

}


/******************************** WIFI功能AT指令 ***************************************/
/**
	* @分类：WiFi模式查询指令
	* @功能：查询ESP8266当前的WiFi工作模式
	* @作用：获取模块当前是STA（客户端）、AP（热点）还是STA+AP模式
	* @param  无
	* @retval	无
	* @note   发送"AT+CWMODE?"指令，查询WiFi工作模式
	*/
void ESP8266_Check_CWMOD(void)
{
    ESP8266_Cmd("AT+CWMODE?", "OK", NULL, 500);
}

/**
	* @分类：WiFi模式配置指令
	* @功能：设置ESP8266的WiFi工作模式
	* @作用：配置模块为STA（连接外部WiFi）、AP（自身作为热点）或STA+AP模式
	* @param  mode：WiFi模式（STA/AP/STA_AP）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CWMODE=<mode>"指令，设置WiFi工作模式
	*/
bool ESP8266_Set_CWMODE(WIFI_MODE_t mode)
{
	switch(mode){
		case STA:
			return ESP8266_Cmd("AT+CWMODE=1", "OK", "no change", 1000);
			break;

		case AP:
			return ESP8266_Cmd("AT+CWMODE=2", "OK", "no change", 1000);
			break;

		case STA_AP:
			return ESP8266_Cmd("AT+CWMODE=3", "OK", "no change", 1000);
			break;

		default:
			return false;
			break;
	}
}

/**
	* @分类：STA连接查询指令
	* @功能：查询ESP8266当前连接的WiFi热点信息
	* @作用：获取已连接的SSID、密码加密方式等信息，确认STA模式连接状态
	* @param  无
	* @retval	无
	* @note   发送"AT+CWJAP?"指令，查询当前连接的WiFi信息
	*/
void ESP8266_Check_CWJAP(void)
{
	ESP8266_Cmd("AT+CWJAP?", "OK", NULL, 500);
}

/**
	* @分类：STA连接配置指令
	* @功能：配置ESP8266连接指定WiFi热点
	* @作用：在STA模式下，连接到指定SSID和密码的WiFi网络
	* @param  ssid：WiFi热点名称；pwd：WiFi密码
	* @retval	bool : 连接是否成功
	* @note   发送"AT+CWJAP_DEF=<ssid>,<pwd>"指令，连接WiFi热点
	*/
bool ESP8266_Set_CWJAP(char *ssid, char *pwd)
{
	char cCmd[120];

	snprintf(cCmd, sizeof(cCmd), "AT+CWJAP=\"%s\", \"%s\"", ssid, pwd);

	return ESP8266_Cmd(cCmd, "OK", NULL, 10000);
}

/**
	* @分类：WiFi扫描指令
	* @功能：扫描周边可用的WiFi热点
	* @作用：获取附近WiFi的SSID、信号强度等信息，用于选择要连接的网络
	* @param  无
	* @retval	无
	* @note   发送"AT+CWLAP"指令，扫描周边WiFi热点
	*/
void ESP8266_Check_CWLAP(void)
{
	ESP8266_Cmd("AT+CWlAP", "OK", NULL, 500);
}

/**
	* @分类：STA断开指令
	* @功能：断开ESP8266与当前WiFi热点的连接
	* @作用：在STA模式下，主动断开与当前网络的连接
	* @param  无
	* @retval	无
	* @note   发送"AT+CWQAP"指令，断开WiFi连接
	*/
void ESP8266_CWQAP(void)
{
	ESP8266_Cmd("AT+CWQAP", "OK", NULL, 500);
}

/**
	* @分类：AP配置查询指令
	* @功能：查询ESP8266的AP模式配置信息
	* @作用：获取模块作为热点时的SSID、密码、信道等参数
	* @param  无
	* @retval	无
	* @note   发送"AT+CWSAP?"指令，查询AP模式配置
	*/
void ESP8266_Check_CWSAP(void)
{
	ESP8266_Cmd("AT+CWSAP?", "OK", NULL, 500);
}

/**
	* @分类：AP配置指令
	* @功能：配置ESP8266的AP模式参数
	* @作用：设置模块作为热点时的SSID、密码、信道和加密方式
	* @param  ssid：热点名称；pwd：热点密码；channel：信道；psdmode：加密方式
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CWSAP=<ssid>,<pwd>,<channel>,<psdmode>"指令，配置AP参数
	*/
bool ESP8266_Set_CWSAP(char *ssid, char *pwd, u8 channel, WIFI_AP_PSDMODE_t psdmode)
{
	char cCmd[120];

	snprintf(cCmd, sizeof(cCmd), "AT+CWSAP=\"%s\", \"%s\", %u, %u", ssid, pwd, channel, psdmode);

	return ESP8266_Cmd(cCmd, "OK", NULL, 1000);
}

/**
	* @分类：AP客户端查询指令
	* @功能：查询连接到ESP8266 AP的客户端设备
	* @作用：获取当前连接到模块热点的设备IP地址，用于管理接入设备
	* @param  无
	* @retval	无
	* @note   发送"AT+CWLIF"指令，查询已连接的客户端
	*/
void ESP8266_CWLIF(void)
{
	ESP8266_Cmd("AT+CWLIF", "OK", NULL, 500);
}

/**
	* @分类：DHCP配置查询指令
	* @功能：查询ESP8266的DHCP功能开关状态
	* @作用：获取STA或AP模式下DHCP是否启用，确认IP地址分配方式
	* @param  无
	* @retval	无
	* @note   发送"AT+CWDHCP?"指令，查询DHCP配置
	*/
void ESP8266_Check_CWDHCP(void)
{
	ESP8266_Cmd("AT+CWDHCP?", "OK", NULL, 500);
}

/**
	* @分类：DHCP配置指令
	* @功能：配置ESP8266的DHCP功能开关
	* @作用：在STA或AP模式下，启用或禁用DHCP（自动获取/分配IP）
	* @param  mode：WiFi模式（STA/AP）；dhcp：DHCP开关（启用/禁用）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CWDHCP=<mode>,<dhcp>"指令，配置DHCP
	*/
bool ESP8266_Set_CWDHCP(WIFI_MODE_t mode, DHCP_MODE_t dhcp)
{
	char cCmd[20];

	snprintf(cCmd, sizeof(cCmd), "AT+CWDHCP=%u, %u", mode, dhcp);

	return ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/**
	* @分类：自动连接配置指令
	* @功能：配置ESP8266的AP自动连接功能
	* @作用：设置模块是否在启动时自动连接到上次连接的WiFi热点
	* @param  ap_mode：自动连接模式（启用/禁用）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CWAUTOCONN=<mode>"指令，配置自动连接
	*/
bool ESP8266_CWAUTOCONN(AUTO_AP_MODE_t ap_mode)
{
	switch(ap_mode){
		case DISABLE_AUTO_AP:
			return ESP8266_Cmd("AT+CWAUTOCONN=0", "OK", NULL, 500);
			break;

		case ENBALE_AUTO_AP:
			return ESP8266_Cmd("AT+CWAUTOCONN=1", "OK", NULL, 500);
			break;

		default:
			return false;
			break;
	}
}

/**
	* @分类：MAC地址查询指令（STA模式）
	* @功能：查询ESP8266在STA模式下的MAC地址
	* @作用：获取模块作为客户端时的物理地址，用于网络访问控制等场景
	* @param  无
	* @retval	无
	* @note   发送"AT+CIPSTAMAC?"指令，查询STA模式MAC地址
	*/
void ESP8266_Check_CIPSTAMAC(void)
{
	ESP8266_Cmd("AT+CIPSTAMAC?", "OK", NULL, 500);
}

/**
	* @分类：MAC地址配置指令（STA模式）
	* @功能：修改ESP8266在STA模式下的MAC地址
	* @作用：自定义模块作为客户端时的物理地址，用于网络身份标识
	* @param  mac：新的MAC地址字符串（格式如"AA:BB:CC:DD:EE:FF"）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CIPSTAMAC=<mac>"指令，设置STA模式MAC地址
	*/
bool ESP8266_Set_CIPSTAMAC(char *mac)
{
	char cCmd[40];

	snprintf(cCmd, sizeof(cCmd), "AT+CIPSTAMAC=\"%s\"", mac);

	return ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/**
	* @分类：MAC地址查询指令（AP模式）
	* @功能：查询ESP8266在AP模式下的MAC地址
	* @作用：获取模块作为热点时的物理地址，用于识别热点身份
	* @param  无
	* @retval	无
	* @note   发送"AT+CIPAPMAC?"指令，查询AP模式MAC地址
	*/
void ESP8266_Check_CIPAPMAC(void)
{
	ESP8266_Cmd("AT+CIPAPMAC?", "OK", NULL, 500);
}

/**
	* @分类：MAC地址配置指令（AP模式）
	* @功能：修改ESP8266在AP模式下的MAC地址
	* @作用：自定义模块作为热点时的物理地址，用于热点身份标识
	* @param  mac：新的MAC地址字符串（格式如"AA:BB:CC:DD:EE:FF"）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CIPAPMAC=<mac>"指令，设置AP模式MAC地址
	*/
bool ESP8266_Set_CIPAPMAC(char *mac)
{
	char cCmd[40];

	snprintf(cCmd, sizeof(cCmd), "AT+CIPAPMAC=\"%s\"", mac);

	return ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/**
	* @分类：IP地址查询指令（STA模式）
	* @功能：查询ESP8266在STA模式下的IP地址配置
	* @作用：获取模块作为客户端时的IP、网关和子网掩码
	* @param  无
	* @retval	无
	* @note   发送"AT+CIPSTA?"指令，查询STA模式IP配置
	*/
void ESP8266_Check_CIPSTA(void)
{
	ESP8266_Cmd("AT+CIPSTA?", "OK", NULL, 500);
}

/**
	* @分类：IP地址配置指令（STA模式）
	* @功能：手动配置ESP8266在STA模式下的IP地址
	* @作用：为模块分配静态IP、网关和子网掩码（当DHCP禁用时）
	* @param  ip：静态IP地址；gateway：网关地址；netmask：子网掩码
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CIPSTA=<ip>,<gateway>,<netmask>"指令，设置STA静态IP
	*/
bool ESP8266_Set_CIPSTA(char *ip, char *gateway, char *netmask)
{
	char cCmd[120];

	snprintf(cCmd, sizeof(cCmd), "AT+CIPSTA=\"%s\",\"%s\",\"%s\"", ip, gateway, netmask);

	return ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/**
	* @分类：IP地址查询指令（AP模式）
	* @功能：查询ESP8266在AP模式下的IP地址配置
	* @作用：获取模块作为热点时的IP、网关和子网掩码（客户端将从该网段获取IP）
	* @param  无
	* @retval	无
	* @note   发送"AT+CIPAP?"指令，查询AP模式IP配置
	*/
void ESP8266_Check_CIPAP(void)
{
	ESP8266_Cmd("AT+CIPAP?", "OK", NULL, 500);
}

/**
	* @分类：IP地址配置指令（AP模式）
	* @功能：手动配置ESP8266在AP模式下的IP地址
	* @作用：为热点分配静态IP、网关和子网掩码，客户端将从该网段获取IP
	* @param  ip：热点IP地址；gateway：网关地址；netmask：子网掩码
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CIPAP=<ip>,<gateway>,<netmask>"指令，设置AP静态IP
	*/
bool ESP8266_Set_CIPAP(char *ip, char *gateway, char *netmask)
{
	char cCmd[40];

	snprintf(cCmd, sizeof(cCmd), "AT+CIPAP=\"%s\",\"%s\",\"%s\"", ip, gateway, netmask);

	return ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/**
	* @分类：智能配网指令
	* @功能：启动ESP8266的智能配网功能
	* @作用：通过ESP-Touch或AirKiss协议，无需手动输入SSID和密码即可配置WiFi
	* @param  type：智能配网类型（ESP-Touch/AirKiss/两者兼容）
	* @retval	bool : 启动是否成功
	* @note   发送"AT+CWSTARTSMART"系列指令，启动智能配网
	*/
bool ESP8266_CWSTARTSMART(SMARTCONFIG_t type)
{
	switch (type)
	{
	case ESP_TOUCH:
		ESP8266_Cmd("AT+CWSTARTSMART=1", "OK", NULL, 500);
		return ESP8266_Cmd("AT+CWSTARTSMART", "OK", NULL, 500);
		break;
	
	case AirKiss:
		ESP8266_Cmd("AT+CWSTARTSMART=2", "OK", NULL, 500);
		return ESP8266_Cmd("AT+CWSTARTSMART", "OK", NULL, 500);
		break;
	
	case ESP_TOUCH_AirKiss:
		ESP8266_Cmd("AT+CWSTARTSMART=3", "OK", NULL, 500);
		return ESP8266_Cmd("AT+CWSTARTSMART", "OK", NULL, 500);
		break;
	
	default:
		return false;
		break;
	}
}

/**
	* @分类：智能配网停止指令
	* @功能：停止ESP8266的智能配网功能
	* @作用：在智能配网超时或完成后，关闭配网模式以节省资源
	* @param  无
	* @retval	bool : 停止是否成功
	* @note   发送"AT+CWSTOPSMART"指令，停止智能配网
	*/
bool ESP8266_CWSTOPSMART(void)
{
	return ESP8266_Cmd("AT+CWSTOPSMART", "OK", NULL, 500);
}

/**
	* @分类：主机名查询指令
	* @功能：查询ESP8266的主机名
	* @作用：获取模块在网络中的标识名称，用于网络设备识别
	* @param  无
	* @retval	无
	* @note   发送"AT+CWHOSTNAME?"指令，查询主机名
	*/
void ESP8266_Check_CWHOSTNAME(void)
{
	ESP8266_Cmd("AT+CWHOSTNAME?", "OK", NULL, 500);
}

/**
	* @分类：主机名配置指令
	* @功能：设置ESP8266的主机名
	* @作用：自定义模块在网络中的标识名称，便于网络设备识别
	* @param  hostname：主机名字符串
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CWHOSTNAME=<hostname>"指令，设置主机名
	*/
bool ESP8266_CWHOSTNAME(char *hostname)
{
	char cCmd[40];

	snprintf(cCmd, sizeof(cCmd), "AT+CWHOSTNAME=\"%s\"", hostname);

	return ESP8266_Cmd(cCmd, "OK", NULL, 500);
}


/******************************** TCP/IP功能AT指令 ***************************************/
/**
	* @分类：连接状态查询指令
	* @功能：获取ESP8266的TCP/IP连接状态
	* @作用：判断模块当前网络连接状态（如未连接/已连接/服务器监听等）
	* @param  无
	* @retval	u8 : 状态码（2=已连接，3=服务器监听，4=断开连接，0=查询失败）
	* @note   发送"AT+CIPSTATUS"指令，解析返回的STATUS字段
	*/
u8 ESP8266_Get_LinkStatus ( void )
{
	if ( ESP8266_Cmd( "AT+CIPSTATUS", "OK", 0, 500 ))
	{
		if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:2\r\n" ) )
			return 2;
		
		else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:3\r\n" ) )
			return 3;
		
		else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:4\r\n" ) )
			return 4;
	}
	
	return 0;
}

/**
	* @分类：多连接状态查询指令
	* @功能：获取ESP8266各连接ID的状态
	* @作用：在多连接模式下，查询每个连接ID（0-4）的连接状态
	* @param  无
	* @retval	u8 : 状态掩码（bit0=ID0，bit1=ID1，...，bit4=ID4，1=已连接）
	* @note   发送"AT+CIPSTATUS"指令，解析各连接ID的状态
	*/
u8 ESP8266_Get_IdLinkStatus ( void )
{
	u8 ucIdLinkStatus = 0x00;
	
	if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) )
	{
		if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:0," ) )
			ucIdLinkStatus |= 0x01;
		else 
			ucIdLinkStatus &= ~ 0x01;
		
		if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:1," ) )
			ucIdLinkStatus |= 0x02;
		else 
			ucIdLinkStatus &= ~ 0x02;
		
		if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:2," ) )
			ucIdLinkStatus |= 0x04;
		else 
			ucIdLinkStatus &= ~ 0x04;
		
		if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:3," ) )
			ucIdLinkStatus |= 0x08;
		else 
			ucIdLinkStatus &= ~ 0x08;
		
		if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:4," ) )
			ucIdLinkStatus |= 0x10;
		else 
			ucIdLinkStatus &= ~ 0x10;	

	}
	
	return ucIdLinkStatus;
	
}

/**
	* @分类：域名解析指令
	* @功能：将域名解析为IP地址
	* @作用：通过域名获取服务器IP，避免直接使用IP地址的局限性
	* @param  domain_name：域名字符串（如"www.example.com"）
	* @retval	bool : 解析是否成功
	* @note   发送"AT+CIPDOMAIN=<domain>"指令，进行域名解析
	*/
bool ESP8266_CIPDOMAIN(char *domain_name)
{
	char cCmd[80];

	snprintf(cCmd, sizeof(cCmd), "AT+CIPDOMAIN=\"%s\"", domain_name);

	return ESP8266_Cmd(cCmd, "OK", NULL, 500);
}

/**
	* @分类：连接模式配置指令
	* @功能：配置ESP8266的TCP连接模式（单连接/多连接）
	* @作用：设置模块支持单个连接还是多个连接（最多5个），适应不同网络场景
	* @param  connect_mode：连接模式（单连接/多连接）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CIPMUX=<mode>"指令，0=单连接，1=多连接
	*/
bool ESP8266_CIPMUX(CONNECTION_MODE_t connect_mode)
{
	switch (connect_mode)
	{
	case Singel_Connection:
		return ESP8266_Cmd("AT+CIPMUX=0", "OK", NULL, 500);
		break;
	
	case Multi_Connection:
		return ESP8266_Cmd("AT+CIPMUX=1", "OK", NULL, 500);
		break;
	
	default:
		return false;
		break;
	}
}

/**
	* @分类：连接建立指令
	* @功能：建立TCP/UDP/SSL连接
	* @作用：与指定IP和端口的服务器建立网络连接，支持多连接ID指定
	* @param  type：网络类型（TCP/UDP/SSL）；remote_ip：服务器IP；remote_port：端口；id：连接ID（多连接模式）
	* @retval	bool : 连接是否成功
	* @note   发送"AT+CIPSTART"指令，建立网络连接
	*/
bool ESP8266_CIPSTART(NET_TYPE_t type, char *remote_ip, u16 remote_port, LINK_ID_t id)
{
	char cStr[100];
	char cCmd[120];

	switch(type){
		case TCP:
			snprintf(cStr, sizeof(cStr), "\"%s\",\"%s\",%u", "TCP", remote_ip, remote_port);
			break;
		
		case UDP:
			snprintf(cStr, sizeof(cStr), "\"%s\",\"%s\",%u", "UDP", remote_ip, remote_port);
			break;

		case SSL:
			snprintf(cStr, sizeof(cStr), "\"%s\",\"%s\",%u", "SSL", remote_ip, remote_port);
			break;

		default:
			break;
	}

	if(id < 5){
		snprintf(cCmd, sizeof(cCmd), "AT+CIPSTART=%u,%s", id, cStr);
	}else{
		snprintf(cCmd, sizeof(cCmd), "AT+CIPSTART=%s", cStr);
	}

	return ESP8266_Cmd(cCmd, "OK", "ALREADY CONNECTED", 2000);
}

/**
	* @分类：SSL缓冲区配置指令
	* @功能：设置ESP8266的SSL缓冲区大小
	* @作用：配置SSL连接的缓冲区大小（2048-4096字节），影响SSL通信性能
	* @param  ssl_buffer_size：缓冲区大小（字节）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CIPSSLSIZE=<size>"指令，设置SSL缓冲区
	*/
bool ESP8266_CIPSSLSIZE(u16 ssl_buffer_size)
{
	if(ssl_buffer_size <= 4096 && ssl_buffer_size >= 2048){
		return ESP8266_Cmd("AT+CIPSSLSIZE=%u", "OK", NULL, 500);
	}else{
		return false;
	}
}

/**
	* @分类：数据发送指令
	* @功能：通过已建立的连接发送数据
	* @作用：向目标服务器发送指定长度的数据，支持透明模式和普通模式
	* @param  link_mode：连接模式（透明/普通）；str：数据内容；str_length：数据长度；id：连接ID
	* @retval	bool : 发送是否成功
	* @note   发送"AT+CIPSEND"指令，在普通模式下需指定长度，透明模式可直接发送
	*/
bool ESP8266_CIPSEND(FunctionalState link_mode, char *str, u32 str_length, LINK_ID_t id)
{
	char cStr[20];
	bool bRet = false;

	if(link_mode){
		ESP8266_Printf("%s", str);
	} else {
		if(id < 5){
			snprintf(cStr, sizeof(cStr), "AT+CIPSEND=%u,%u", id, str_length + 2);
		} else {
			snprintf(cStr, sizeof(cStr), "AT+CIPSEND=%u", str_length + 2);
		}

		ESP8266_Cmd(cStr, "> ", NULL, 500);

		bRet = ESP8266_Cmd(str, "SEND OK", NULL, 500);
	}

	return bRet;
}

/**
	* @分类：连接关闭指令
	* @功能：关闭指定的TCP/IP连接
	* @作用：断开与服务器的连接，释放网络资源
	* @param  id：连接ID（多连接模式）
	* @retval	bool : 关闭是否成功
	* @note   发送"AT+CIPCLOSE=<id>"指令，关闭指定连接
	*/
bool ESP8266_CIPCLOSE(LINK_ID_t id)
{
	return ESP8266_Cmd("AT+CIPCLOSE=%u", "OK", NULL, 500);
}

/**
	* @分类：AP模式IP获取指令
	* @功能：获取ESP8266在AP模式下的IP地址
	* @作用：提取模块作为热点时的IP地址，用于客户端连接配置
	* @param  pAP_IP：存储IP地址的缓冲区；IP_Buf_Length：缓冲区长度
	* @retval 0：失败 1：成功
	* @note   发送"AT+CIFSR"指令，解析返回的APIP字段
	*/
u8 ESP8266_AP_IP(char *pAP_IP, u8 IP_Buf_Length)
{
	char uc;
	char *pCh;

	ESP8266_Cmd("AT+CIFSR", "OK", NULL, 500);

	pCh = strstr(strEsp8266_Fram_Record.Data_RX_BUF, "APIP,\"");

	if(pCh)	{pCh += 6;}
	else	{return 0;}

	for(uc = 0; uc < IP_Buf_Length; uc++){
		pAP_IP [uc] = *(pCh + uc);
		if(pAP_IP[uc] == '\"'){
			pAP_IP[uc] = '\0';
			break;
		}
	}

	return 1;

}

/**
	* @分类：超时设置指令
	* @功能：设置ESP8266的TCP连接超时时间
	* @作用：配置连接建立或数据传输的超时时间（毫秒），避免无限等待
	* @param  pTimeOver：超时时间（毫秒）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CIPSTO=<time>"指令，设置超时时间
	*/
bool ESP8266_STOP(u16 pTimeOver)
{
	return ESP8266_Cmd("AT+CIPSTO=%u", "OK", NULL, 500);
}

/**
	* @分类：TCP服务器配置指令
	* @功能：启动或关闭ESP8266的TCP服务器功能
	* @作用：在指定端口启动TCP服务器，或关闭已运行的服务器
	* @param  mode：服务器模式（启用/禁用）；port：端口号；pTimeOver：超时时间
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CIPSERVER=<mode>,<port>"指令，配置TCP服务器
	*/
bool ESP8266_TCPSERVER(FunctionalState mode, char *port, u16 pTimeOver)
{
	char cCmd1[120];

	if(mode){
		snprintf(cCmd1, sizeof(cCmd1), "AT+CIPSERVER=%u,%s", 1, port);
	
		return (ESP8266_Cmd(cCmd1, "OK", NULL, 500) && ESP8266_STOP(pTimeOver));
	} else {
		snprintf(cCmd1, sizeof(cCmd1), "AT+CIPSERVER=%u,%s", 0, port);

		return ESP8266_Cmd(cCmd1, "OK", NULL, 500);
	}
}

/**
	* @分类：传输模式查询指令
	* @功能：查询ESP8266当前的数据传输模式
	* @作用：判断模块当前是普通模式（需AT指令前缀）还是透明传输模式（直接发送数据）
	* @param  无
	* @retval	无
	* @note   发送"AT+CIPMODE?"指令，查询传输模式
	*/
void ESP8266_Check_CIPMODE(void)
{
	ESP8266_Cmd("AT+CIPMODE?", "OK", NULL, 500);
}

/**
	* @分类：传输模式配置指令
	* @功能：配置ESP8266的数据传输模式
	* @作用：切换普通模式（需AT指令）和透明传输模式（直接发送数据，适合连续通信）
	* @param  mode：传输模式（普通/透明）
	* @retval	bool : 配置是否成功
	* @note   发送"AT+CIPMODE=<mode>"指令，0=普通模式，1=透明模式
	*/
bool ESP8266_Set_CIPMODE(TRANSFER_MODE_t mode)
{
	switch(mode){
		case NORMAL_MODE:
			return ESP8266_Cmd("AT+CIPMODE=0", "OK", NULL, 1000);
			break;
		
		case TRANSPARENT_MODE:
			return ESP8266_Cmd("AT+CIPMODE=1", "OK", NULL, 1000);
	}
}

/**
	* @分类：网络检测指令
	* @功能：向指定IP发送Ping请求
	* @作用：检测与目标IP的网络连通性，验证网络链路是否通畅
	* @param  IP：目标IP地址
	* @retval	bool : Ping是否成功
	* @note   发送"AT+PING=<ip>"指令，执行Ping操作
	*/
bool ESP8266_Ping(char *IP)
{
	return ESP8266_Cmd("AT+PING=\"%s\"", "OK", NULL, 500);
}

/**
	* @分类：透明传输退出指令
	* @功能：从透明传输模式切换回普通模式
	* @作用：在透明模式下，通过发送特殊序列退出，重新允许AT指令操作
	* @param  无
	* @retval	无
	* @note   发送"+++"序列（无回车），延迟后退出透明模式
	*/
void ESP8266_ExitUnvarnishSend(void)
{
	Delay_s(1);
	ESP8266_Printf("+++");
	Delay_ms(500);
}

/**
	* @分类：数据接收指令
	* @功能：接收ESP8266收到的网络数据
	* @作用：从接收缓冲区读取完整数据帧，支持普通模式和透明模式
	* @param  enumEnUnvarnishTx：是否为透明传输模式
	* @retval	char* : 接收数据的缓冲区指针（NULL表示无有效数据）
	* @note   等待帧接收完成后，返回数据缓冲区地址
	*/
char * ESP8266_ReceiveString ( FunctionalState enumEnUnvarnishTx )
{
	char * pRecStr = 0;
	
	strEsp8266_Fram_Record .InfBit .FramLength = 0;
	strEsp8266_Fram_Record .InfBit .FramFinishFlag = 0;
	
	while ( ! strEsp8266_Fram_Record .InfBit .FramFinishFlag );
	strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0';
	
	if ( enumEnUnvarnishTx ){
		pRecStr = strEsp8266_Fram_Record .Data_RX_BUF;
	} else {
		if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+IPD" ) ){
			pRecStr = strEsp8266_Fram_Record .Data_RX_BUF;
		}
	}

	return pRecStr;
}
